home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / Terminal 2.2 / Project / Sources / File.c < prev    next >
Text File  |  1992-01-17  |  19KB  |  767 lines

  1. /*
  2.     Terminal 2.2
  3.     "File.c"
  4. */
  5.  
  6. #ifdef THINK_C
  7. #include "MacHeaders"
  8. #endif
  9. #ifdef applec
  10. #pragma load ":(Objects):MacHeadersMPW"
  11. #pragma segment Main2
  12. #endif
  13.  
  14. #include "File.h"
  15. #include "Text.h"
  16. #include "Main.h"
  17. #include "Strings.h"
  18. #include "Utilities.h"
  19. #include "MySF.h"
  20. #include "Document.h"
  21. #include "Port.h"
  22. #include "CancelDialog.h"
  23. #include "XModem.h"
  24. #include "ZModem.h"
  25. #include "MacBinary.h"
  26. #include "FormatStr.h"
  27. #include "Interp.h"
  28.  
  29. /* ----- Static data --------------------------------------------------- */
  30.  
  31. static jmp_buf env;
  32. static short ScriptRef;            /* Script file reference */
  33. static short ScriptUnget;        /* Script file unget buffer */
  34. static Byte *ScriptBuffer;        /* Script file buffer */
  35. static long ScriptEob;            /* Size of script file buffer */
  36. static long ScriptMark;            /* Next position in script file buffer */
  37. extern INTRINSIC Intrinsics[];    /* Script intrinsic functions */
  38.  
  39. /* ----- Text capture -------------------------------------------------- */
  40.  
  41. void TextCapture(short options)
  42. {
  43.     register DocumentPeek window = TerminalWindow;
  44.     SFReply sfr;
  45.     short r;
  46.  
  47.     /* If capture is on the off */
  48.  
  49.     if (window->file) {
  50.         if (window->length) {
  51.             if (FSWrite(window->file, &window->length, window->record))
  52.                 SysBeep(1);
  53.         }
  54.         FSClose(window->file);
  55.         FlushVol(0, window->volume);
  56.         window->file = window->volume = 0;
  57.         window->length = 0;
  58.         SetItemStyle(GetMenu(FILE), CAPTURE, 0);
  59.         return;
  60.     }
  61.  
  62.     /* If capture is off then on */
  63.  
  64.     if (options & (optionKey | cmdKey | shiftKey | controlKey)) {
  65.         /* Append to existing file */
  66.         MySFGetFile(MyString(STR_G, G_APPEND), 0, 1, &TEXT, &sfr, 0);
  67.         if (!sfr.good)    /* Cancel */
  68.             return;
  69.         if (OpenFile(sfr.vRefNum, 0, (Byte *)sfr.fName, &r)) {
  70.             SysBeep(1);
  71.             return;
  72.         }
  73.         if (SetFPos(r, fsFromLEOF, 0)) {
  74.             FSClose(r);
  75.             SysBeep(1);
  76.             return;
  77.         }
  78.     } else {
  79.         /* Open new file */
  80.         MySFPutFile(MyString(STR_G, G_SAVE), MyString(STR_G, G_CTFILE),
  81.             MyString(STR_G, G_CAPTURE), &sfr);
  82.         if (!sfr.good)    /* Cancel */
  83.             return;
  84.         DeleteFile(sfr.vRefNum, 0, (Byte *)sfr.fName);
  85.         if (CreateFile(sfr.vRefNum, 0, (Byte *)sfr.fName,
  86.                 Settings.textCreator, TEXT) ||
  87.                 OpenFile(sfr.vRefNum, 0, (Byte *)sfr.fName, &r)) {
  88.             SysBeep(1);
  89.             return;
  90.         }
  91.     }
  92.     window->file = r;
  93.     window->volume = sfr.vRefNum;
  94.     SetItemStyle(GetMenu(FILE), CAPTURE, ACTIVE);
  95. }
  96.  
  97. /* ----- Save one byte in capture file --------------------------------- */
  98.  
  99. void ByteCapture(register Byte b)
  100. {
  101.     register DocumentPeek window = TerminalWindow;
  102.     register short err;
  103.  
  104.     if (window->file) {
  105.         window->record[(window->length)++] = b;
  106.         if (window->length == RECORD) {
  107.             err = FSWrite(window->file, &window->length, window->record);
  108.             window->length = 0;
  109.             if (err) {
  110.                 TextCapture(0);    /* Close file */
  111.                 Error(err, EmptyStr);
  112.             }
  113.         }
  114.     }
  115. }
  116.  
  117. /* ----- Save text of window ------------------------------------------- */
  118.  
  119. void SaveBuffer(short options)
  120. {
  121.     register DocumentPeek window = TerminalWindow;
  122.     register Byte *p;
  123.     register short err;
  124.     SFReply sfr;
  125.     short r;
  126.     long count;
  127.  
  128.     if (window->buf.newChar == window->buf.firstChar)    /* Empty */
  129.         return;
  130.     if (options & (optionKey | cmdKey | shiftKey | controlKey)) {
  131.         /* Append to existing file */
  132.         MySFGetFile(MyString(STR_G, G_APPEND), 0, 1, &TEXT, &sfr, 0);
  133.         RedrawDocument();
  134.         if (!sfr.good)    /* Cancel */
  135.             return;
  136.         if (OpenFile(sfr.vRefNum, 0, (Byte *)sfr.fName, &r))
  137.             goto done2;
  138.         if (SetFPos(r, fsFromLEOF, 0))
  139.             goto done1;
  140.     } else {
  141.         /* Create new file */
  142.         MySFPutFile(MyString(STR_G, G_SAVE), MyString(STR_G, G_SCBUFFER),
  143.             MyString(STR_G, G_BUFFER), &sfr);
  144.         RedrawDocument();
  145.         if (!sfr.good)    /* Cancel */
  146.             return;
  147.         DeleteFile(sfr.vRefNum, 0, (Byte *)sfr.fName);
  148.         if ((err = CreateFile(sfr.vRefNum, 0, (Byte *)sfr.fName,
  149.                 Settings.textCreator, TEXT)) ||
  150.                 (err = OpenFile(sfr.vRefNum, 0, (Byte *)sfr.fName, &r)))
  151.             goto done2;
  152.     }
  153.     p = window->buf.text;
  154.     if (window->buf.newChar > window->buf.firstChar) {    /* One part */
  155.         count = window->buf.newChar - window->buf.firstChar;
  156.         err = FSWrite(r, &count, p + window->buf.firstChar);
  157.     } else {                                            /* Two parts */
  158.         count = window->buf.size - window->buf.firstChar;
  159.         if (err = FSWrite(r, &count, p + window->buf.firstChar))
  160.             goto done1;
  161.         if (count = window->buf.newChar)
  162.             err = FSWrite(r, &count, p);
  163.     }
  164. done1:
  165.     FSClose(r);
  166.     FlushVol(0, sfr.vRefNum);
  167. done2:
  168.     if (err)
  169.         Error(err, EmptyStr);
  170. }
  171.  
  172. /* ----- Send text file ------------------------------------------------ */
  173.  
  174. short pascal SendTextFile(
  175.     short ref,                    /* File reference number */
  176.     Byte *name)                    /* File name */
  177. {
  178.     register short err;            /* Error code */
  179.     register long count;        /* File read count */
  180.     register Byte buffer[256];    /* Transmit buffer */
  181.     HParamBlockRec p;            /* Used for PBRead() */
  182.     long mark = 0;                /* Current file position */
  183.     long time;                    /* How long it takes */
  184.  
  185.     if (SendFileRef || Sending || Transfer)
  186.         return fBsyErr;
  187.     SendFileRef = ref;
  188.     Sending = TRUE;
  189.     Control_X = FALSE;
  190.     SetItemStyle(GetMenu(FILE), SEND, ACTIVE);
  191.     MakeMessage(TerminalWindow,
  192.         FormatStr(buffer, MyString(STR_P, P_STEXT), name));
  193.     /* SerialHandshake(Settings.handshake); */
  194.     p.ioParam.ioCompletion = 0;
  195.     p.ioParam.ioRefNum = ref;
  196.     p.ioParam.ioBuffer = (Ptr)buffer;
  197.     p.ioParam.ioReqCount = (Settings.chardelay) ? 1 : sizeof(buffer) - 1;
  198.     p.ioParam.ioPosMode =
  199.         (Settings.linedelay || Settings.prompt[0] || Settings.autoLF) ?
  200.         (0x0D80 | fsAtMark) : fsAtMark;    /* CR as newline (if necessary) */
  201.     time = Time;
  202.     do {
  203.         err = PBRead((ParmBlkPtr)&p, FALSE);
  204.         count = p.ioParam.ioActCount;
  205.         if ((err == noErr || err == eofErr) && count) {
  206.             while (Busy)    /* Other send in progress */
  207.                 ;
  208.             if (buffer[count-1] == '\015') {
  209.                 if (Settings.autoLF)
  210.                     buffer[count++] = '\012';
  211.                 SerialSend(buffer, count, &Busy);
  212.                 if (Settings.localEcho)
  213.                     NewCharacters(buffer, count, FALSE);
  214.                 if (Settings.linedelay || Settings.prompt[0])
  215.                     Loop(Settings.linedelay,Settings.prompt,1);
  216.                 else
  217.                     CheckEvents();
  218.             } else {
  219.                 SerialSend(buffer, count, &Busy);
  220.                 if (Settings.localEcho)
  221.                     NewCharacters(buffer, count, FALSE);
  222.                 if (Settings.chardelay)
  223.                     Loop(Settings.chardelay, 0, 0);
  224.                 else
  225.                     CheckEvents();
  226.             }
  227.             mark += count;
  228.         }
  229.     } while (err == noErr && Sending);
  230.  
  231.     if (err == eofErr)
  232.         err = noErr;
  233.     if (!Sending)
  234.         err = Control_X ? ABORT : CANCEL;
  235.     Statistics(mark, time = Time - time, err);
  236.     SetItemStyle(GetMenu(FILE), SEND, 0);
  237.     FSClose(ref);
  238.     SendFileRef = 0;
  239.     Sending = FALSE;
  240.     Control_X = FALSE;
  241.     /* SerialHandshake(0); */
  242.     return err;
  243. }
  244.  
  245. /* ----- Get text file name and send text file ------------------------- */
  246.  
  247. void SendText(void)
  248. {
  249.     register short err;
  250.     SFReply sfr;
  251.     short r;
  252.  
  253.     if (Transfer) {
  254.         SysBeep(1);
  255.         return;
  256.     }
  257.     if (!Sending) {
  258.         MySFGetFile(MyString(STR_G, G_SEND), 0, 1, &TEXT, &sfr, 0);
  259.         RedrawDocument();
  260.         if (!sfr.good)
  261.             return;
  262.         if (err = OpenFile(sfr.vRefNum, 0, (Byte *)sfr.fName, &r)) {
  263.             Error(err, EmptyStr);
  264.             return;
  265.         }
  266.         err = SendTextFile(r, (Byte *)sfr.fName);
  267.     } else {
  268.         SerialAbort();
  269.         Sending = FALSE;
  270.     }
  271. }
  272.  
  273. /* ----- Send text ----------------------------------------------------- */
  274.  
  275. static short TypeText(
  276.     register Byte *s,            /* -> text to send */
  277.     register long n)            /* Number of characters in text */
  278. {
  279.     register long count;        /* File read count */
  280.     register Byte buffer[256];    /* Transmit buffer */
  281.     short req;                    /* Max byte count */
  282.     Boolean cr;                    /* Look for CR */
  283.     short err;                    /* Error code */
  284.     long mark = 0;                /* Current file position */
  285.     long time;                    /* How long it takes */
  286.  
  287.     Sending = TRUE;
  288.     Control_X = FALSE;
  289.     SetItemStyle(GetMenu(EDIT), PASTE, ACTIVE);
  290.     MakeMessage(TerminalWindow,
  291.         FormatStr(buffer, MyString(STR_P, P_SSCRAP)));
  292.     /* SerialHandshake(Settings.handshake); */
  293.     if (Settings.chardelay) {
  294.         req = 1;
  295.         cr = FALSE;
  296.     } else {
  297.         req = sizeof(buffer) - 1;
  298.         cr = Settings.linedelay || Settings.prompt[0] || Settings.autoLF;
  299.     }
  300.     time = Time;
  301.     do {
  302.         count = (req < n) ? req : n;
  303.         if (cr) {
  304.             Byte *s1;
  305.             if (s1 = memchr(s, 13, count))
  306.                 count = s1 - s + 1;
  307.         }
  308.         n -= count;
  309.         memcpy(buffer, s, count);
  310.         s += count;
  311.         if (count) {
  312.             while (Busy)    /* Other send in progress */
  313.                 ;
  314.             if (buffer[count-1] == '\015') {
  315.                 if (Settings.autoLF)
  316.                     buffer[count++] = '\012';
  317.                 SerialSend(buffer, count, &Busy);
  318.                 if (Settings.localEcho)
  319.                     NewCharacters(buffer, count, FALSE);
  320.                 if (Settings.linedelay || Settings.prompt[0])
  321.                     Loop(Settings.linedelay, Settings.prompt, 1);
  322.                 else
  323.                     CheckEvents();
  324.             } else {
  325.                 SerialSend(buffer, count, &Busy);
  326.                 if (Settings.localEcho)
  327.                     NewCharacters(buffer, count, FALSE);
  328.                 if (Settings.chardelay)
  329.                     Loop(Settings.chardelay, 0, 0);
  330.                 else
  331.                     CheckEvents();
  332.             }
  333.             mark += count;
  334.         }
  335.     } while (n && Sending);
  336.     if (!n)
  337.         err = noErr;
  338.     if (!Sending)
  339.         err = Control_X ? ABORT : CANCEL;
  340.     /* Statistics(mark, time = Time - time, err); */
  341.     SetItemStyle(GetMenu(EDIT), PASTE, 0);
  342.     Sending = FALSE;
  343.     Control_X = FALSE;
  344.     /* SerialHandshake(0); */
  345.     return err;
  346. }
  347.  
  348. /* ----- Send TEXT from scrap ------------------------------------------ */
  349.  
  350. void SendScrap(void)
  351. {
  352.     register Handle h;
  353.     register long err;
  354.     long offset;
  355.  
  356.     if (Transfer) {
  357.         SysBeep(1);
  358.         return;
  359.     }
  360.     if (Sending) {
  361.         SerialAbort();
  362.         Sending = FALSE;
  363.     } else {
  364.         if (h = NewHandle(0)) {
  365.             if ((err = GetScrap(h,TEXT,&offset)) > 0) {
  366.                 HLock(h);
  367.                 TypeText((Byte *)*h, err);
  368.                 err = noErr;
  369.             }
  370.             DisposHandle(h);
  371.         } else
  372.             err = memFullErr;
  373.         if (err)
  374.             Error(err, EmptyStr);
  375.     }
  376. }
  377.  
  378. /* ----- Receive file -------------------------------------------------- */
  379.  
  380. void FileReceive(void)
  381. {
  382.     register short err;
  383.     SFReply sfr;
  384.  
  385.     if (Sending) {
  386.         SysBeep(1);
  387.         return;
  388.     }
  389.     if (!Transfer) {
  390.         if (Settings.ZModem) {
  391.             err = ZReceive();
  392.             UnloadSeg(ZReceive);
  393.         } else
  394.             if (Settings.batch) {
  395.                 err = XReceive(EmptyStr, 0, 0);
  396.                 UnloadSeg(XReceive);
  397.             } else {
  398.                 MySFPutFile(MyString(STR_G, G_RECEIVE),
  399.                     MyString(STR_G, G_SFRECEIVE),
  400.                     MyString(STR_G, G_DOWNLOAD), &sfr);
  401.                 RedrawDocument();
  402.                 if (sfr.good) {
  403.                     DeleteFile(sfr.vRefNum, 0, (Byte *)sfr.fName);
  404.                     err = XReceive((Byte *)sfr.fName, sfr.vRefNum, 0);
  405.                     UnloadSeg(XReceive);
  406.                 }
  407.             }
  408.     } else
  409.         Transfer = 0;    /* Cancel transfer */
  410. }
  411.  
  412. /* ----- Transmit file ------------------------------------------------- */
  413.  
  414. void FileTransmit(void)
  415. {
  416.     register short err;
  417.     SFReply sfr;
  418.  
  419.     if (Sending) {
  420.         SysBeep(1);
  421.         return;
  422.     }
  423.     if (!Transfer) {
  424.         MySFGetFile (MyString(STR_G, G_TRANSMIT), 0, -1, 0, &sfr, 0);
  425.         RedrawDocument();
  426.         if (sfr.good) {
  427.             if (Settings.ZModem) {
  428.                 err = ZTransmit((Byte *)sfr.fName, sfr.vRefNum, 0);
  429.                 UnloadSeg(ZTransmit);
  430.             } else {
  431.                 err = XTransmit((Byte *)sfr.fName, sfr.vRefNum, 0);
  432.                 UnloadSeg(XTransmit);
  433.             }
  434.         }
  435.     } else
  436.         Transfer = 0;    /* Cancel transfer */
  437. }
  438.  
  439. /* ----- Make MacBinary file ------------------------------------------- */
  440.  
  441. short Convert(
  442.     short volume1, long dir1, Byte *name1,
  443.     short volume2, long dir2, Byte *name2)
  444. {
  445.     register short err, err2;
  446.     register Handle buf;
  447.     register unsigned long size;
  448.     Boolean mf;
  449.     short ref2;
  450.     long count;
  451.  
  452.     if ((err = BinOpenRead(volume1, dir1, name1)) ||
  453.             (err = CreateFile(volume2, dir2, name2, Application.signature,
  454.                 Application.btype)) ||
  455.             (err = OpenFile(volume2, dir2, name2, &ref2)))
  456.         return err;
  457.     if ((size = MaxBuffer(&mf)) < 128 || !(buf = NewBuffer(size, mf)))
  458.         return memFullErr;
  459.     err2 = 0;
  460.     do {
  461.         count = size;
  462.         if (!(err = BinRead(&count, (Byte *)*buf)) || err == eofErr)
  463.             err2 = FSWrite(ref2, &count, *buf);
  464.     } while(!err && !err2);
  465.     DisposeBuffer(buf, mf);
  466.     BinCloseRead();
  467.     FSClose(ref2);
  468.     FlushVol(0, volume2);
  469.     if (err == eofErr)
  470.         err = 0;
  471.     return err2 ? err2 : err;
  472. }
  473.  
  474. void Make(void)
  475. {
  476.     SFReply r1, r2;
  477.     register Byte *suffix;
  478.     register Byte name[256];
  479.     register long n;
  480.     register short err;
  481.  
  482.     suffix = MyString(STR_G, G_BIN);
  483.     MySFGetFile(MyString(STR_G, G_MAKE), 0, -1, 0, &r1, 0);
  484.     if (!r1.good)
  485.         return;
  486.     RedrawDocument();
  487.     memcpy(name, r1.fName, n = (r1.fName[0] + 1));
  488.     memcpy(name + n, suffix + 1, suffix[0]);
  489.     name[0] += suffix[0];
  490.     MySFPutFile(MyString(STR_G, G_SAVE), MyString(STR_G, G_MAKENAME),
  491.         name, &r2);
  492.     if (!r2.good)
  493.         return;
  494.     RedrawDocument();
  495.     DeleteFile(r2.vRefNum, 0, (Byte *)r2.fName);
  496.     if (err = Convert(r1.vRefNum, 0, (Byte *)r1.fName,
  497.             r2.vRefNum, 0, (Byte *)r2.fName))
  498.         Error(err, EmptyStr);
  499. }
  500.  
  501. /* ----- Extract from MacBinary file ----------------------------------- */
  502.  
  503. short CopyFile(register short ref1)
  504. {
  505.     register short err, err2;
  506.     long count;
  507.     register Handle buf;
  508.     register unsigned long size;
  509.     Boolean mf;
  510.  
  511.     if ((size = MaxBuffer(&mf)) < 128 || !(buf = NewBuffer(size, mf)))
  512.         return memFullErr;
  513.     err2 = 0;
  514.     do {
  515.         count = size;
  516.         if (!(err = FSRead(ref1, &count, *buf)) || err == eofErr)
  517.             err2 = BinWrite(&count, (Byte *)*buf);
  518.     } while(!err && !err2);
  519.     DisposeBuffer(buf, mf);
  520.     if (err == eofErr)
  521.         err = 0;
  522.     return err ? err : err2;
  523. }
  524.  
  525. void Extract(void)
  526. {
  527.     SFReply r1, r2;
  528.     short ref1;
  529.     Byte name[64];
  530.     Byte header[BinHeaderLength];
  531.     long count, data, resource;
  532.     register short err, err2;
  533.  
  534.     MySFGetFile(MyString(STR_G, G_EXTRACT), 0, -1, 0, &r1, 0);
  535.     if (!r1.good)
  536.         return;
  537.     RedrawDocument();
  538.  
  539.     if (err = OpenFile(r1.vRefNum, 0, (Byte *)r1.fName, &ref1))
  540.         goto sorry1;
  541.  
  542.     count = sizeof(header);
  543.     if ((err = FSRead(ref1, &count, header)) || count != sizeof(header))
  544.         goto sorry;
  545.  
  546.     if (!BinCheckHeader(header, name, &data, &resource)) {
  547.         err = 1;
  548.         goto sorry;
  549.     }
  550.  
  551.     MySFPutFile(MyString(STR_G, G_SAVE), MyString(STR_G, G_SFEXTRACT),
  552.         name, &r2);
  553.     if (!r2.good)
  554.         goto sorry;
  555.     RedrawDocument();
  556.  
  557.     DeleteFile(r2.vRefNum, 0, (Byte *)r2.fName);
  558.     if (err = CreateFile(r2.vRefNum, 0, (Byte *)r2.fName, '????', '????'))
  559.         goto sorry;
  560.  
  561.     if (err = BinOpenWrite(r2.vRefNum, 0, (Byte *)r2.fName, header))
  562.         goto sorry;
  563.  
  564.     err = CopyFile(ref1);
  565.     err2 = BinCloseWrite();
  566.     if (!err)
  567.         err = err2;
  568.  
  569. sorry:
  570.     FSClose(ref1);
  571. sorry1:
  572.     if (err)
  573.         Error(err, EmptyStr);
  574. }
  575.  
  576. /* ----- Get text file name and execute script ------------------------- */
  577.  
  578. #define SCRIPTSIZE    512                /* Script file buffer size */
  579. #define SCRIPTMAX    Config.script    /* Memory size for script */
  580.  
  581. static Boolean Script(void)
  582. {
  583.     register short err;
  584.     register Boolean quit = FALSE;
  585.     Options save;
  586.  
  587.     ScriptBuffer = 0;
  588.     if (!(ScriptBuffer = (Byte *)NewPtr(SCRIPTSIZE + SCRIPTMAX))) {
  589.         err = MemError();
  590.         goto done;
  591.     }
  592.     ScriptUnget = -1;            /* No unget character yet */
  593.     ScriptMark = ScriptEob = SCRIPTSIZE;    /* Buffer is still empty */
  594.  
  595.     save = Settings;            /* Save settings */
  596.     if (setjmp(env) == 0) {
  597.         SI_Load(Intrinsics, ScriptBuffer + SCRIPTSIZE, SCRIPTMAX);
  598.         FSClose(ScriptRef);        /* Script file no longer needed */
  599.         ScriptRef = 0;
  600.         err = SI_Interpret();    /* Call main() in script */
  601.     } else {                    /* Come here after error */
  602.         err = 1;                /* Always restore settings if error */
  603.         SysBeep(1);
  604.     }
  605.     /*
  606.         The script main() can return the following values:
  607.             0    : Don't restore saved settings, continue application
  608.             1    : Restore saved settings, continue application
  609.             256    : Don't restore saved settings, quit application
  610.             257    : Restore saved settings, quit application
  611.     */
  612.     if (err == 1 || err == 257) {    /* Restore settings */
  613.         if (save.portSetup != Settings.portSetup ||
  614.                 !EqualString(save.portName, Settings.portName, FALSE, TRUE) ||
  615.                 save.handshake != Settings.handshake) {
  616.             SerialClose();
  617.             SerialOpen(save.portName, save.portSetup, save.handshake);
  618.         }
  619.         Settings = save;
  620.     }
  621.     if (err == 256 || err == 257)    /* Quit application */
  622.         quit = TRUE;
  623.     err = noErr;
  624.  
  625. done:
  626.     if (ScriptBuffer)
  627.         DisposPtr((Ptr)ScriptBuffer);
  628.     if (ScriptRef)
  629.         FSClose(ScriptRef);
  630.     if (err) {
  631.         SysBeep(1);
  632.         Error(err, EmptyStr);
  633.     }
  634.     return quit;
  635. }
  636.  
  637. static Boolean ScriptFlag = 0;
  638.  
  639. Boolean RunScript(
  640.     short volume,
  641.     long directory,
  642.     Byte *name,
  643.     short item)
  644. {
  645.     register short err;
  646.     register Byte *n;
  647.     register Boolean quit = FALSE;
  648.     SFReply sfr;
  649.  
  650.     if (Transfer) {
  651.         SysBeep(1);
  652.         return quit;
  653.     }
  654.     if (ScriptFlag) {        /* Cancel script */
  655.         Abort = TRUE;
  656.         Sending = FALSE;
  657.         SerialAbort();
  658.     } else {                /* Execute script file */
  659.         if (name)
  660.             err = OpenFile(volume, directory, n = name, &ScriptRef);
  661.         else {
  662.             MySFGetFile(MyString(STR_G,G_SCRIPT),
  663.                 MyString(STR_G,G_SUFFIX),
  664.                 1, &TEXT, &sfr, 0);
  665.             RedrawDocument();
  666.             if (!sfr.good)
  667.                 return quit;
  668.             err = OpenFile(sfr.vRefNum, 0, n = (Byte *)sfr.fName,
  669.                 &ScriptRef);
  670.         }
  671.         if (err) {
  672.             Error(err, EmptyStr);
  673.             return quit;
  674.         }
  675.         Abort = FALSE;
  676.         ScriptFlag = item;
  677.         SetWTitle((WindowPtr)TerminalWindow, n);
  678.         SetItemStyle(GetMenu(SCRIPT), item, ACTIVE);
  679.         quit = Script();
  680.         SetItemStyle(GetMenu(SCRIPT), item, 0);
  681.         Abort = TRUE;
  682.         ScriptFlag = 0;
  683.     }
  684.     return quit;
  685. }
  686.  
  687. Boolean DoMenuScript(register short item)
  688. {
  689.     register Byte name[256];
  690.  
  691.     GetItem(GetMenu(SCRIPT), item, name);
  692.     Append(name, MyString(STR_G, G_SUFFIX));
  693.     return RunScript(Settings.scriptVolume, Settings.scriptDirectory, name, item);
  694. }
  695.  
  696. /* ----- Functions called by interpreter ------------------------------- */
  697.  
  698. void SI_Error(
  699.     register short erno,
  700.     register Byte *s,
  701.     register short line)
  702. {
  703.     register Byte message[256];
  704.  
  705.     erno += 2;
  706.     if (*s) {
  707.         CtoPstr((char *)s);
  708.         FormatStr(message,MyString(STR_S,1),s,MyString(STR_S,erno),line);
  709.         PtoCstr((Byte *)s);
  710.     } else
  711.         FormatStr(message,MyString(STR_S,2),MyString(STR_S,erno),line);
  712.     MakeMessage(TerminalWindow, message);
  713.     longjmp(env, 0);    /* Return to Script(), ignore link chain */
  714. }
  715.  
  716. short SI_GetSource(void)
  717. {
  718.     register Byte c;
  719.  
  720.     if (ScriptUnget >= 0) {            /* The was a previous unget */
  721.         c = ScriptUnget;            /* So use the unget buffer */
  722.         ScriptUnget = -1;            /* Unget buffer is empty now */
  723.         return c;
  724.     }
  725.     if (ScriptMark < ScriptEob)        /* Can still use buffer */
  726.         return ScriptBuffer[ScriptMark++];
  727.     if (ScriptEob < SCRIPTSIZE)        /* Was last (partial) buffer */
  728.         return -1;                    /* EOF */
  729.     ScriptEob = SCRIPTSIZE;            /* Read next buffer from file */
  730.     FSRead(ScriptRef, &ScriptEob, ScriptBuffer);
  731.     if (ScriptEob > 0) {            /* Ok, at least one character */
  732.         ScriptMark = 0;
  733.         return SI_GetSource();
  734.     }
  735.     return -1;                        /* Error or end of file */
  736. }
  737.  
  738. void SI_UngetSource(register short c)
  739. {
  740.     ScriptUnget = c;                /* That's easy */
  741. }
  742.  
  743. /* ----- Kiss script file ---------------------------------------------- */
  744.  
  745. void Kiss(short options)
  746. {
  747.     SFReply r;
  748.     ParamBlockRec p;
  749.     register OSType creator;
  750.  
  751.     creator = (options & (optionKey | cmdKey | shiftKey | controlKey)) ?
  752.         Settings.textCreator : Application.signature;
  753.     do {
  754.         MySFGetFile(MyString(STR_G,G_KISS), MyString(STR_G,G_SUFFIX),
  755.             1, &TEXT, &r, creator);
  756.         if (r.good) {
  757.             memset(&p, 0, sizeof(p));
  758.             p.fileParam.ioNamePtr = r.fName;
  759.             p.fileParam.ioVRefNum = r.vRefNum;
  760.             if (!PBGetFInfo(&p, FALSE)) {
  761.                 p.fileParam.ioFlFndrInfo.fdCreator = creator;
  762.                 PBSetFInfo(&p, FALSE);
  763.             }
  764.         }
  765.     } while (FALSE /* r.good */);
  766. }
  767.